home *** CD-ROM | disk | FTP | other *** search
- /* tio.c */
-
- /* Author:
- * Steve Kirkendall
- * 14407 SW Teal Blvd. #C
- * Beaverton, OR 97005
- * kirkenda@cs.pdx.edu
- */
-
-
- /* This file contains terminal I/O functions */
-
- #include "config.h"
- #include "vi.h"
- #include "ctype.h"
-
-
- /* This function reads in a line from the terminal. */
- int vgets(prompt, buf, bsize)
- char prompt; /* the prompt character, or '\0' for none */
- char *buf; /* buffer into which the string is read */
- int bsize; /* size of the buffer */
- {
- int len; /* how much we've read so far */
- int ch; /* a character from the user */
- int quoted; /* is the next char quoted? */
- int tab; /* column position of cursor */
- char widths[132]; /* widths of characters */
- int word; /* index of first letter of word */
- #ifndef NO_DIGRAPH
- int erased; /* 0, or first char of a digraph */
- #endif
-
- /* show the prompt */
- move(LINES - 1, 0);
- tab = 0;
- if (prompt)
- {
- addch(prompt);
- tab = 1;
- }
- clrtoeol();
- refresh();
-
- /* read in the line */
- #ifndef NO_DIGRAPH
- erased =
- #endif
- quoted = len = 0;
- for (;;)
- {
- #ifndef NO_ABBR
- if (quoted || mode == MODE_EX)
- {
- ch = getkey(0);
- }
- else
- {
- /* maybe expand an abbreviation while getting key */
- for (word = len; --word >= 0 && isalnum(buf[word]); )
- {
- }
- word++;
- ch = getabkey(WHEN_EX, &buf[word], len - word);
- }
- #else
- ch = getkey(0);
- #endif
- #ifndef NO_EXTENSIONS
- if (ch == ctrl('O'))
- {
- ch = getkey(quoted ? 0 : WHEN_EX);
- }
- #endif
-
- /* some special conversions */
- if (ch == ctrl('D') && len == 0)
- ch = ctrl('[');
- #ifndef NO_DIGRAPH
- if (*o_digraph && erased != 0 && ch != '\b')
- {
- ch = digraph(erased, ch);
- erased = 0;
- }
- #endif
-
- /* inhibit detection of special chars (except ^J) after a ^V */
- if (quoted && ch != '\n')
- {
- ch |= 256;
- }
-
- /* process the character */
- switch(ch)
- {
- case ctrl('V'):
- qaddch('^');
- qaddch('\b');
- quoted = TRUE;
- break;
-
- case ctrl('['):
- return -1;
-
- case '\n':
- #if OSK
- case '\l':
- #else
- case '\r':
- #endif
- clrtoeol();
- goto BreakBreak;
-
- case '\b':
- if (len > 0)
- {
- len--;
- #ifndef NO_DIGRAPH
- erased = buf[len];
- #endif
- for (ch = widths[len]; ch > 0; ch--)
- addch('\b');
- if (mode == MODE_EX)
- {
- clrtoeol();
- }
- tab -= widths[len];
- }
- else
- {
- return -1;
- }
- break;
-
- default:
- /* strip off quotation bit */
- if (ch & 256)
- {
- ch &= ~256;
- qaddch(' ');
- qaddch('\b');
- }
-
- /* add & echo the char */
- if (len < bsize - 1)
- {
- if (ch == '\t' && !quoted)
- {
- widths[len] = *o_tabstop - (tab % *o_tabstop);
- addstr(" " + 8 - widths[len]);
- tab += widths[len];
- }
- else if (ch > 0 && ch < ' ') /* > 0 by GB */
- {
- addch('^');
- addch(ch + '@');
- widths[len] = 2;
- tab += 2;
- }
- else if (ch == '\177')
- {
- addch('^');
- addch('?');
- widths[len] = 2;
- tab += 2;
- }
- else
- {
- addch(ch);
- widths[len] = 1;
- tab++;
- }
- buf[len++] = ch;
- }
- else
- {
- beep();
- }
- quoted = FALSE;
- }
- }
- BreakBreak:
- refresh();
- buf[len] = '\0';
- return len;
- }
-
-
- static int manymsgs; /* This variable keeps msgs from overwriting each other */
- static char pmsg[80]; /* previous message (waiting to be displayed) */
-
-
- static int showmsg()
- {
- /* if there is no message to show, then don't */
- if (!manymsgs)
- return FALSE;
-
- /* display the message */
- move(LINES - 1, 0);
- if (*pmsg)
- {
- standout();
- qaddch(' ');
- qaddstr(pmsg);
- qaddch(' ');
- standend();
- }
- clrtoeol();
-
- manymsgs = FALSE;
- return TRUE;
- }
-
-
- void endmsgs()
- {
- if (manymsgs)
- {
- showmsg();
- addch('\n');
- }
- }
-
- /* Write a message in an appropriate way. This should really be a varargs
- * function, but there is no such thing as vwprintw. Hack!!!
- *
- * In MODE_EX or MODE_COLON, the message is written immediately, with a
- * newline at the end.
- *
- * In MODE_VI, the message is stored in a character buffer. It is not
- * displayed until getkey() is called. msg() will call getkey() itself,
- * if necessary, to prevent messages from being lost.
- *
- * msg("") - clears the message line
- * msg("%s %d", ...) - does a printf onto the message line
- */
- /*VARARGS1*/
- void msg(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
- char *fmt;
- long arg1, arg2, arg3, arg4, arg5, arg6, arg7;
- {
- if (mode != MODE_VI)
- {
- sprintf(pmsg, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
- qaddstr(pmsg);
- addch('\n');
- exrefresh();
- }
- else
- {
- /* wait for keypress between consecutive msgs */
- if (manymsgs)
- {
- getkey(WHEN_MSG);
- }
-
- /* real message */
- sprintf(pmsg, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
- if (*fmt)
- {
- manymsgs = TRUE;
- }
- }
- }
-
-
- /* This function calls refresh() if the option exrefresh is set */
- void exrefresh()
- {
- char *scan;
-
- /* If this ex command wrote ANYTHING set exwrote so vi's : command
- * can tell that it must wait for a user keystroke before redrawing.
- */
- for (scan=kbuf; scan<stdscr; scan++)
- if (*scan == '\n')
- exwrote = TRUE;
-
- /* now we do the refresh thing */
- if (*o_exrefresh)
- {
- refresh();
- }
- else
- {
- wqrefresh();
- }
- if (mode != MODE_VI)
- {
- manymsgs = FALSE;
- }
- }
-
-
- /* This structure is used to store maps and abbreviations. The distinction
- * between them is that maps are stored in the list referenced by the "maps"
- * pointer, while abbreviations are referenced by the "abbrs" pointer.
- */
- typedef struct _map
- {
- struct _map *next; /* another abbreviation */
- short len; /* length of the "rawin" characters */
- short flags; /* various flags */
- char *label; /* label of the map/abbr, or NULL */
- char *rawin; /* the "rawin" characters */
- char *cooked;/* the "cooked" characters */
- } MAP;
-
- static char keybuf[KEYBUFSIZE];
- static int cend; /* end of input characters */
- static int user; /* from user through end are chars typed by user */
- static int next; /* index of the next character to be returned */
- static MAP *match; /* the matching map, found by countmatch() */
- static MAP *maps; /* the map table */
- #ifndef NO_ABBR
- static MAP *abbrs; /* the abbreviation table */
- #endif
-
-
-
- /* ring the terminal's bell */
- void beep()
- {
- /* do a visible/audible bell */
- if (*o_flash)
- {
- do_VB();
- refresh();
- }
- else if (*o_errorbells)
- {
- ttywrite("\007", 1);
- }
-
- /* discard any buffered input, and abort macros */
- next = user = cend;
- }
-
-
-
- /* This function replaces a "rawin" character sequence with the "cooked" version,
- * by modifying the internal type-ahead buffer.
- */
- void execmap(rawlen, cookedstr, visual)
- int rawlen; /* length of rawin text -- string to delete */
- char *cookedstr; /* the cooked text -- string to insert */
- int visual; /* boolean -- chars to be executed in visual mode? */
- {
- int cookedlen;
- char *src, *dst;
- int i;
-
- /* find the length of the cooked string */
- cookedlen = strlen(cookedstr);
- #ifndef NO_EXTENSIONS
- if (visual)
- {
- cookedlen *= 2;
- }
- #endif
-
- /* if too big to fit in type-ahead buffer, then don't do it */
- if (cookedlen + (cend - next) - rawlen > KEYBUFSIZE)
- {
- return;
- }
-
- /* shift to make room for cookedstr at the front of keybuf */
- src = &keybuf[next + rawlen];
- dst = &keybuf[cookedlen];
- i = cend - (next + rawlen);
- if (src >= dst)
- {
- while (i-- > 0)
- {
- *dst++ = *src++;
- }
- }
- else
- {
- src += i;
- dst += i;
- while (i-- > 0)
- {
- *--dst = *--src;
- }
- }
-
- /* insert cookedstr, and adjust offsets */
- cend += cookedlen - rawlen - next;
- user += cookedlen - rawlen - next;
- next = 0;
- for (dst = keybuf, src = cookedstr; *src; )
- {
- #ifndef NO_EXTENSIONS
- if (visual)
- {
- *dst++ = ctrl('O');
- cookedlen--;
- }
- #endif
- *dst++ = *src++;
- }
-
- #ifdef DEBUG2
- {
- #include <stdio.h>
- FILE *debout;
- int i;
-
- debout = fopen("debug.out", "a");
- fprintf(debout, "After execmap(%d, \"%s\", %d)...\n", rawlen, cookedstr, visual);
- for (i = 0; i < cend; i++)
- {
- if (i == next) fprintf(debout, "(next)");
- if (i == user) fprintf(debout, "(user)");
- if (UCHAR(keybuf[i]) < ' ')
- fprintf(debout, "^%c", keybuf[i] ^ '@');
- else
- fprintf(debout, "%c", keybuf[i]);
- }
- fprintf(debout, "(end)\n");
- fclose(debout);
- }
- #endif
- }
-
- /* This function calls ttyread(). If necessary, it will also redraw the screen,
- * change the cursor shape, display the mode, and update the ruler. If the
- * number of characters read is 0, and we didn't time-out, then it exits because
- * we've apparently reached the end of an EX script.
- */
- static int fillkeybuf(when, timeout)
- int when; /* mixture of WHEN_XXX flags */
- int timeout;/* timeout in 1/10 second increments, or 0 */
- {
- int nkeys;
- #ifndef NO_SHOWMODE
- static int oldwhen; /* "when" from last time */
- static int oldleft;
- static long oldtop;
- static long oldnlines;
- char *str;
- #endif
- #ifndef NO_CURSORSHAPE
- static int oldcurs;
- #endif
-
- #ifdef DEBUG
- watch();
- #endif
-
-
- #ifndef NO_CURSORSHAPE
- /* make sure the cursor is the right shape */
- if (has_CQ)
- {
- if (when != oldcurs)
- {
- switch (when)
- {
- case WHEN_EX: do_CX(); break;
- case WHEN_VICMD: do_CV(); break;
- case WHEN_VIINP: do_CI(); break;
- case WHEN_VIREP: do_CR(); break;
- }
- oldcurs = when;
- }
- }
- #endif
-
- #ifndef NO_SHOWMODE
- /* if "showmode" then say which mode we're in */
- if (*o_smd && (when & WHENMASK))
- {
- /* redraw the screen before we check to see whether the
- * "showmode" message needs to be redrawn.
- */
- redraw(cursor, !(when & WHEN_VICMD));
-
- /* now the "topline" test should be valid */
- if (when != oldwhen || topline != oldtop || leftcol != oldleft || nlines != oldnlines)
- {
- oldwhen = when;
- oldtop = topline;
- oldleft = leftcol;
- oldnlines = nlines;
-
- if (when & WHEN_VICMD) str = "Command";
- else if (when & WHEN_VIINP) str = " Input ";
- else if (when & WHEN_VIREP) str = "Replace";
- else if (when & WHEN_REP1) str = " Rep 1 ";
- else if (when & WHEN_CUT) str = "BufName";
- else if (when & WHEN_MARK) str = "Mark AZ";
- else if (when & WHEN_CHAR) str = "Dest Ch";
- else str = (char *)0;
-
- if (str)
- {
- move(LINES - 1, COLS - 10);
- standout();
- qaddstr(str);
- standend();
- }
- }
- }
- #endif
-
- #ifndef NO_EXTENSIONS
- /* maybe display the ruler */
- if (*o_ruler && (when & (WHEN_VICMD|WHEN_VIINP|WHEN_VIREP)))
- {
- char buf[20];
-
- redraw(cursor, !(when & WHEN_VICMD));
- pfetch(markline(cursor));
- sprintf(buf, "%7ld,%-4d", markline(cursor), 1 + idx2col(cursor, ptext, when & (WHEN_VIINP|WHEN_VIREP)));
- move(LINES - 1, COLS - 22);
- addstr(buf);
- }
- #endif
-
- /* redraw, so the cursor is in the right place */
- if (when & WHENMASK)
- {
- redraw(cursor, !(when & (WHENMASK & ~(WHEN_VIREP|WHEN_VIINP))));
- }
-
- /* Okay, now we can finally read the rawin keystrokes */
- refresh();
- nkeys = ttyread(keybuf + cend, sizeof keybuf - cend, timeout);
-
- /* if nkeys == 0 then we've reached EOF of an ex script. */
- if (nkeys == 0 && timeout == 0)
- {
- tmpabort(TRUE);
- move(LINES - 1, 0);
- clrtoeol();
- refresh();
- endwin();
- exit(1);
- }
-
- cend += nkeys;
- user += nkeys;
- return nkeys;
- }
-
-
- /* This function counts the number of maps that could match the characters
- * between &keybuf[next] and &keybuf[cend], including incomplete matches.
- * The longest comlete match is remembered via the "match" variable.
- */
- static int countmatch(when)
- int when; /* mixture of WHEN_XXX flags */
- {
- MAP *map;
- int count;
-
- /* clear the "match" variable */
- match = (MAP *)0;
-
- /* check every map */
- for (count = 0, map = maps; map; map = map->next)
- {
- /* can't match if wrong mode */
- if ((map->flags & when) == 0)
- {
- continue;
- }
-
- /* would this be a complete match? */
- if (map->len <= cend - next)
- {
- /* Yes, it would be. Now does it really match? */
- if (!strncmp(map->rawin, &keybuf[next], map->len))
- {
- count++;
-
- /* if this is the longest complete match,
- * then remember it.
- */
- if (!match || match->len < map->len)
- {
- match = map;
- }
- }
- }
- else
- {
- /* No, it wouldn't. But check for partial match */
- if (!strncmp(map->rawin, &keybuf[next], cend - next))
- {
- count++;
- }
- }
- }
- return count;
- }
-
-
- #ifndef NO_ABBR
- /* This function checks to see whether a word is an abbreviation. If it is,
- * then an appropriate number of backspoace characters is inserted into the
- * type-ahead buffer, followed by the expanded form of the abbreviation.
- */
- static void expandabbr(word, wlen)
- char *word;
- int wlen;
- {
- MAP *abbr;
-
- /* if the next character wouldn't end the word, then don't expand */
- if (isalnum(keybuf[next]) || keybuf[next] == ctrl('V'))
- {
- return;
- }
-
- /* find the abbreviation, if any */
- for (abbr = abbrs;
- abbr && (abbr->len != wlen || strncmp(abbr->rawin, word, wlen));
- abbr = abbr->next)
- {
- }
-
- /* If an abbreviation was found, then expand it by inserting the long
- * version into the type-ahead buffer, and then inserting (in front of
- * the long version) enough backspaces to erase to the short version.
- */
- if (abbr)
- {
- execmap(0, abbr->cooked, FALSE);
- while (wlen > 15)
- {
- execmap(0, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", FALSE);
- wlen -= 15;
- }
- if (wlen > 0)
- {
- execmap(0, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" + 15 - wlen, FALSE);
- }
- }
- }
- #endif
-
-
- /* This function calls getabkey() without attempting to expand abbreviations */
- int getkey(when)
- int when; /* mixture of WHEN_XXX flags */
- {
- return getabkey(when, "", 0);
- }
-
-
- /* This is it. This function returns keystrokes one-at-a-time, after mapping
- * and abbreviations have been taken into account.
- */
- int getabkey(when, word, wlen)
- int when; /* mixture of WHEN_XXX flags */
- char *word; /* a word that may need to be expanded as an abbr */
- int wlen; /* length of "word" -- since "word" might not have \0 */
- {
- int matches;
-
- /* if this key is needed for delay between multiple error messages,
- * then reset the manymsgs flag and abort any mapped key sequence.
- */
- if (showmsg())
- {
- if (when == WHEN_MSG)
- {
- #ifndef CRUNCH
- if (!*o_more)
- {
- refresh();
- return ' ';
- }
- #endif
- qaddstr("[More...]");
- refresh();
- execmap(user, "", FALSE);
- }
- }
-
- #ifdef DEBUG
- /* periodically check for screwed up internal tables */
- watch();
- #endif
-
- /* if buffer empty, read some characters without timeout */
- if (next >= cend)
- {
- next = user = cend = 0;
- fillkeybuf(when, 0);
- }
-
- /* try to map the key, unless already mapped and not ":set noremap" */
- if (next >= user || *o_remap)
- {
- do
- {
- do
- {
- matches = countmatch(when);
- } while (matches > 1 && fillkeybuf(when, *o_keytime) > 0);
- if (matches == 1)
- {
- execmap(match->len, match->cooked,
- (match->flags & WHEN_INMV) != 0
- && (when & (WHEN_VIINP|WHEN_VIREP)) != 0);
- }
- } while (*o_remap && matches == 1);
- }
-
- #ifndef NO_ABBR
- /* try to expand an abbreviation, except in visual command mode */
- if (wlen > 0 && (mode & (WHEN_EX|WHEN_VIINP|WHEN_VIREP)) != 0)
- {
- expandabbr(word, wlen);
- }
- #endif
-
- /* ERASEKEY should always be mapped to '\b'. */
- if (keybuf[next] == ERASEKEY)
- {
- keybuf[next] = '\b';
- }
-
- /* return the next key */
- return keybuf[next++];
- }
-
- /* This function maps or unmaps a key */
- void mapkey(rawin, cooked, when, name)
- char *rawin; /* the input key sequence, before mapping */
- char *cooked;/* after mapping -- or NULL to remove map */
- short when; /* bitmap of when mapping should happen */
- char *name; /* name of the key, NULL for no name, "abbr" for abbr */
- {
- MAP **head; /* head of list of maps or abbreviations */
- MAP *scan; /* used for scanning through the list */
- MAP *prev; /* used during deletions */
-
- /* Is this a map or an abbreviation? Choose the right list. */
- #ifndef NO_ABBR
- head = ((!name || strcmp(name, "abbr")) ? &maps : &abbrs);
- #else
- head = &maps;
- #endif
-
- /* try to find the map in the list */
- for (scan = *head, prev = (MAP *)0;
- scan && (strcmp(rawin, scan->rawin) ||
- !(scan->flags & when & (WHEN_EX|WHEN_VICMD|WHEN_VIINP|WHEN_VIREP)));
- prev = scan, scan = scan->next)
- {
- }
-
- /* trying to map? (not unmap) */
- if (cooked && *cooked)
- {
- /* if map starts with "visual ", then mark it as a visual map */
- if (head == &maps && !strncmp(cooked, "visual ", 7))
- {
- cooked += 7;
- when |= WHEN_INMV;
- }
-
- /* "visual" maps always work in input mode */
- if (when & WHEN_INMV)
- {
- when |= WHEN_VIINP|WHEN_VIREP|WHEN_POPUP;
- }
-
- /* if not already in the list, then allocate a new structure */
- if (!scan)
- {
- scan = (MAP *)malloc(sizeof(MAP));
- scan->len = strlen(rawin);
- scan->rawin = malloc(scan->len + 1);
- strcpy(scan->rawin, rawin);
- scan->flags = when;
- scan->label = name;
- if (*head)
- {
- prev->next = scan;
- }
- else
- {
- *head = scan;
- }
- scan->next = (MAP *)0;
- }
- else /* recycle old structure */
- {
- free(scan->cooked);
- }
- scan->cooked = malloc(strlen(cooked) + 1);
- strcpy(scan->cooked, cooked);
- }
- else /* unmapping */
- {
- /* if nothing to unmap, then exit silently */
- if (!scan)
- {
- return;
- }
-
- /* unlink the structure from the list */
- if (prev)
- {
- prev->next = scan->next;
- }
- else
- {
- *head = scan->next;
- }
-
- /* free it, and the strings that it refers to */
- free(scan->rawin);
- free(scan->cooked);
- free(scan);
- }
- }
-
-
- /* This function returns a printable version of a string. It uses tmpblk.c */
- char *printable(str)
- char *str; /* the string to convert */
- {
- char *build; /* used for building the string */
-
- for (build = tmpblk.c; *str; str++)
- {
- #if AMIGA
- if (*str == '\233')
- {
- *build++ = '<';
- *build++ = 'C';
- *build++ = 'S';
- *build++ = 'I';
- *build++ = '>';
- } else
- #endif
- if (UCHAR(*str) < ' ' || *str == '\177')
- {
- *build++ = '^';
- *build++ = *str ^ '@';
- }
- else
- {
- *build++ = *str;
- }
- }
- *build = '\0';
- return tmpblk.c;
- }
-
- /* This function displays the contents of either the map table or the
- * abbreviation table. User commands call this function as follows:
- * :map dumpkey(WHEN_VICMD, FALSE);
- * :map! dumpkey(WHEN_VIREP|WHEN_VIINP, FALSE);
- * :abbr dumpkey(WHEN_VIINP|WHEN_VIREP, TRUE);
- * :abbr! dumpkey(WHEN_EX|WHEN_VIINP|WHEN_VIREP, TRUE);
- */
- void dumpkey(when, abbr)
- int when; /* WHEN_XXXX of mappings to be dumped */
- int abbr; /* boolean: dump abbreviations instead of maps? */
- {
- MAP *scan;
- char *str;
- int len;
-
- #ifndef NO_ABBR
- for (scan = (abbr ? abbrs : maps); scan; scan = scan->next)
- #else
- for (scan = maps; scan; scan = scan->next)
- #endif
- {
- /* skip entries that don't match "when" */
- if ((scan->flags & when) == 0)
- {
- continue;
- }
-
- /* dump the key label, if any */
- if (!abbr)
- {
- len = 8;
- if (scan->label)
- {
- qaddstr(scan->label);
- len -= strlen(scan->label);
- }
- do
- {
- qaddch(' ');
- } while (len-- > 0);
- }
-
- /* dump the rawin version */
- str = printable(scan->rawin);
- qaddstr(str);
- len = strlen(str);
- do
- {
- qaddch(' ');
- } while (len++ < 8);
-
- /* dump the mapped version */
- #ifndef NO_EXTENSIONS
- if ((scan->flags & WHEN_INMV) && (when & (WHEN_VIINP|WHEN_VIREP)))
- {
- qaddstr("visual ");
- }
- #endif
- str = printable(scan->cooked);
- qaddstr(str);
- addch('\n');
- exrefresh();
- }
- }
-
- #ifndef NO_MKEXRC
-
- static safequote(str)
- char *str;
- {
- char *build;
-
- build = tmpblk.c + strlen(tmpblk.c);
- while (*str)
- {
- if (*str <= ' ' && *str >= 1 || *str == '|')
- {
- *build++ = ctrl('V');
- }
- *build++ = *str++;
- }
- *build = '\0';
- }
-
- /* This function saves the contents of either the map table or the
- * abbreviation table into a file. Both the "bang" and "no bang" versions
- * are saved.
- * :map dumpkey(WHEN_VICMD, FALSE);
- * :map! dumpkey(WHEN_VIREP|WHEN_VIINP, FALSE);
- * :abbr dumpkey(WHEN_VIINP|WHEN_VIREP, TRUE);
- * :abbr! dumpkey(WHEN_EX|WHEN_VIINP|WHEN_VIREP, TRUE);
- */
- savemaps(fd, abbr)
- int fd; /* file descriptor of an open file to write to */
- int abbr; /* boolean: do abbr table? (else do map table) */
- {
- MAP *scan;
- char *str;
- int bang;
- int when;
- int len;
-
- # ifndef NO_ABBR
- for (scan = (abbr ? abbrs : maps); scan; scan = scan->next)
- # else
- for (scan = maps; scan; scan = scan->next)
- # endif
- {
- /* skip maps that have labels, except for function keys */
- if (scan->label && *scan->label != '#')
- {
- continue;
- }
-
- for (bang = 0; bang < 2; bang++)
- {
- /* decide which "when" flags we want */
- # ifndef NO_ABBR
- if (abbr)
- when = (bang ? WHEN_EX|WHEN_VIINP|WHEN_VIREP : WHEN_VIINP|WHEN_VIREP);
- else
- # endif
- when = (bang ? WHEN_VIREP|WHEN_VIINP : WHEN_VICMD);
-
- /* skip entries that don't match "when" */
- if ((scan->flags & when) == 0)
- {
- continue;
- }
-
- /* write a "map" or "abbr" command name */
- # ifndef NO_ABBR
- if (abbr)
- strcpy(tmpblk.c, "abbr");
- else
- # endif
- strcpy(tmpblk.c, "map");
-
- /* maybe write a bang. Definitely write a space */
- if (bang)
- strcat(tmpblk.c, "! ");
- else
- strcat(tmpblk.c, " ");
-
- /* write the rawin version */
- # ifndef NO_FKEY
- if (scan->label)
- strcat(tmpblk.c, scan->label);
- else
- # endif
- safequote(scan->rawin);
- strcat(tmpblk.c, " ");
-
- /* dump the mapped version */
- # ifndef NO_EXTENSIONS
- if ((scan->flags & WHEN_INMV) && (when & (WHEN_VIINP|WHEN_VIREP)))
- {
- strcat(tmpblk.c, "visual ");
- }
- # endif
- safequote(scan->cooked);
- strcat(tmpblk.c, "\n");
- twrite(fd, tmpblk.c, strlen(tmpblk.c));
- }
- }
- }
- #endif
-